Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

255
Visualizações
Error "Se esperaba que la operación de la base de datos afectara a 1 fila(s) pero en realidad afectó a 0 fila(s)" al agregar una entidad relacionada

He estado buscando una solución para escribir un método de actualización "genérico" en EF Core que actualice todas las propiedades modificadas de una entidad, incluida una colección relacionada. La razón de esto es que almaceno las traducciones del nombre de una entidad en una tabla diferente. Encontré esta solución que parecía funcionar bien al principio, pero luego me di cuenta de que aparece un error "Se esperaba que la operación de la base de datos afectara a 1 fila (s) pero en realidad afectó a 0 fila (s)" cuando lo único que cambié en el entidad estaba agregando una nueva traducción de nombre en la tabla relacionada TblProjectTranslations . Aquí está mi código:

 public async Task UpdateProjectAsync(TblProject updatedEntity) { TblProject dbEntity = Context.TblProjects .Include(dbEntity => dbEntity.TblProjectTranslations) .SingleOrDefault(dbEntity => dbEntity.ProjectId == updatedEntity.ProjectId); if (dbEntity != null) { Context.Entry(dbEntity).CurrentValues.SetValues(updatedEntity); foreach (TblProjectTranslation dbTranslation in dbEntity.TblProjectTranslations.ToList()) { if (!updatedEntity.TblProjectTranslations .Any(translation => translation.ProjectId == dbTranslation.ProjectId && translation.Language == dbTranslation.Language)) { Context.TblProjectTranslations.Remove(dbTranslation); } } foreach (TblProjectTranslation newTranslation in updatedEntity.TblProjectTranslations) { TblProjectTranslation dbTranslation = dbEntity.TblProjectTranslations .SingleOrDefault(dbTranslation => dbTranslation.ProjectId == newTranslation.ProjectId && dbTranslation.Language == newTranslation.Language); if (dbTranslation != null) { Context.Entry(dbTranslation).CurrentValues.SetValues(newTranslation); } else { dbEntity.TblProjectTranslations.Add(newTranslation); } } await Context.SaveChangesAsync(); } }

Estas son las clases de ingeniería inversa de EF Core:

 public partial class TblProject { public TblProject() { TblProjectTranslations = new HashSet<TblProjectTranslation>(); } public int ProjectId { get; set; } public virtual ICollection<TblProjectTranslation> TblProjectTranslations { get; set; } } public partial class TblProjectTranslation { public int ProjectId { get; set; } public string Language { get; set; } public string ProjectName { get; set; } public virtual TblProject Project { get; set; } }

Así es como se definen en OnModelCreating :

 modelBuilder.Entity<TblProject>(entity => { entity.HasKey(e => e.ProjectId); entity.ToTable("TBL_project"); entity.Property(e => e.ProjectId).HasColumnName("project_ID"); }); modelBuilder.Entity<TblProjectTranslation>(entity => { entity.HasKey(e => new { e.ProjectId, e.Language }); entity.ToTable("TBL_project_translation"); entity.HasIndex(e => e.ProjectId, "IX_TBL_project_translation_project_ID"); entity.Property(e => e.ProjectId).HasColumnName("project_ID"); entity.Property(e => e.Language) .HasMaxLength(5) .HasColumnName("language") .HasDefaultValueSql("('-')"); entity.Property(e => e.ProjectName) .IsRequired() .HasMaxLength(50) .HasColumnName("project_name") .HasDefaultValueSql("('-')"); entity.HasOne(d => d.Project) .WithMany(p => p.TblProjectTranslations) .HasForeignKey(d => d.ProjectId) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("TBL_project_translation_TBL_project"); });

Lo que no entiendo es que dbEntity.TblProjectTranslations.Add(newTranslation) parece ser el problema. Cuando reemplazo esta línea con await Context.TblProjectTranslations.AddAsync(newTranslation) , el error "mágicamente" desaparece, pero ¿no se supone que ambas formas deben hacer básicamente lo mismo? Aquí hay un ejemplo de una updatedEntity y una dbEntity de base de datos que capturé mientras depuraba la función justo antes de que ocurriera el problema:

 updatedEntity: ProjectId: 41 TblProjectTranslations: 1 Entry with: Language: "en" Project: null ProjectId: 41 ProjectName: "TestNameEN" dbEntity: ProjectId: 41 TblProjectTranslations: No entries

¿Que esta pasando aqui? Ni siquiera tengo ningún activador en la base de datos en ambas tablas que parecían ser la causa de este error para otras personas.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Después de jugar un poco con el modelo de muestra, el código y las explicaciones, finalmente pude reproducirlo. El culpable parece ser la clave compuesta y el valor predeterminado para la parte de la cadena:

 entity.HasKey(e => new { e.ProjectId, e.Language }); // (1) entity.Property(e => e.Language) .HasMaxLength(5) .HasColumnName("language") .HasDefaultValueSql("('-')"); // (2)

Lo mismo sucede si usas

 .HasDefaultValue("-")

Esta combinación de alguna manera hace que EF considere el elemento agregado a la propiedad de navegación de la colección principal

 dbEntity.TblProjectTranslations.Add(newTranslation);

como Modified en lugar de Added , lo que luego conduce al error en cuestión.

Dado que no puedo encontrar una explicación de dicho comportamiento en la documentación de EF Core y, en general, se ve mal, sugeriría ir e informarlo al rastreador de problemas de EF Core GitHub .

Mientras tanto, las posibles soluciones que veo son

  • Eliminar .HasDefaultValueSql / .HasDefaultValue para la columna de clave

  • En lugar de agregar el elemento secundario a la colección principal, agréguelo directamente al contexto o al DbSet correspondiente (opcionalmente, configure la propiedad de navegación de referencia de antemano "por si acaso"):

 newTranslation.Project = dbEntity; Context.Add(newTranslation);
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda